
#include <QFontDatabase>

#include "core/engine.h"
#include "core/game.h"
#include "ui/ui.h"
#include "core/scene.h"
#include "core/view.h"

Engine* Engine::s_pkInstance = NULL;

Engine::Engine(QObject* pkParent)
    : QObject(pkParent),
      m_pkFMODEventSystem(NULL),
      m_pkGame(NULL),
      m_pkUi(NULL),
      m_pkView(NULL),
      m_pkScene(NULL)

{
    qsrand(QTime::currentTime().msec());
    int iID = QFontDatabase::addApplicationFont(":/fonts/Wortellina.ttf");
    Q_ASSERT(iID >= 0);
}

Engine::~Engine()
{
    m_kTimer.stop();
    delete m_pkView;

    FMOD_RESULT kResult = FMOD_EventGroup_FreeEventData(m_pkFMODEventGroup, NULL, 1);
    Q_ASSERT(kResult == FMOD_OK);

    kResult = FMOD_EventSystem_Release(m_pkFMODEventSystem);
    Q_ASSERT(kResult == FMOD_OK);
}

Engine& Engine::instance()
{
    if(!s_pkInstance)
        s_pkInstance = new Engine();

    return *s_pkInstance;
}

FMOD_EVENTSYSTEM* Engine::fmod() const
{
    return m_pkFMODEventSystem;
}

Game& Engine::game() const
{
    return *m_pkGame;
}

Ui& Engine::ui() const
{
    return *m_pkUi;
}

View& Engine::view() const
{
    return *m_pkView;
}

Scene& Engine::scene() const
{
    return *m_pkScene;
}

void Engine::initialize()
{
    // Instanciation.
    m_pkGame = new Game(this);
    m_pkScene = new Scene(this);

    m_pkView = new View(NULL);
    m_pkUi = new Ui(NULL);

    Q_CHECK_PTR(m_pkGame);
    Q_CHECK_PTR(m_pkUi);
    Q_CHECK_PTR(m_pkView);
    Q_CHECK_PTR(m_pkScene);

    // FMOD setup.
    FMOD_RESULT kResult = FMOD_EventSystem_Create(&m_pkFMODEventSystem);
    Q_ASSERT(kResult == FMOD_OK);
    kResult = FMOD_EventSystem_Init(m_pkFMODEventSystem, 256, FMOD_INIT_NORMAL, 0, FMOD_EVENT_INIT_NORMAL);
    Q_ASSERT(kResult == FMOD_OK);
    kResult = FMOD_EventSystem_Load(m_pkFMODEventSystem, "sound/melomaniac.fev", 0, 0);
    Q_ASSERT(kResult == FMOD_OK);
    kResult = FMOD_EventSystem_GetGroup(m_pkFMODEventSystem, "melomaniac/melomaniac", 1, &m_pkFMODEventGroup);
    Q_ASSERT(kResult == FMOD_OK);
    kResult = FMOD_EventGroup_LoadEventData(m_pkFMODEventGroup, FMOD_EVENT_RESOURCE_STREAMS_AND_SAMPLES, FMOD_EVENT_DEFAULT);
    Q_ASSERT(kResult == FMOD_OK);

    // QGraphics framework setup.
    m_pkScene->initialize();
    m_pkScene->addWidget(m_pkUi);
    m_pkView->setScene(m_pkScene);
    m_pkView->show();

    // Setup loop.
    m_kTimer.setInterval(s_updateDelay);
    connect(&m_kTimer, SIGNAL(timeout()), m_pkScene, SLOT(step()));
    connect(&m_kTimer, SIGNAL(timeout()), m_pkScene, SLOT(update()));

    // FMOD theme start.
    FMOD_EVENT* pkFMODEventTheme;
    kResult = FMOD_EventSystem_GetEvent(Engine::instance().fmod(), "melomaniac/melomaniac/theme", FMOD_EVENT_DEFAULT, &pkFMODEventTheme);
    Q_ASSERT(kResult == FMOD_OK);
    kResult = FMOD_Event_Start(pkFMODEventTheme);
    Q_ASSERT(kResult == FMOD_OK);
}

void Engine::start()
{
    m_kTimer.start();
}

void Engine::stop()
{
    m_kTimer.stop();
}
